Skip to content

feat(ratchet): rule the business-semantics ceiling to 100,000 and decouple the README banner - #1606

Merged
os-steve merged 4 commits into
mainfrom
claude/issue-1601-ratchet-reanchor-100k
Sep 5, 2026
Merged

feat(ratchet): rule the business-semantics ceiling to 100,000 and decouple the README banner#1606
os-steve merged 4 commits into
mainfrom
claude/issue-1601-ratchet-reanchor-100k

Conversation

@os-steve

@os-steve os-steve commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

Fixes #1601

pnpm verify is green, all eight stages, including both suites that import
CEILINGS/BUFFER passing on their re-expressed relations.

The maintainer ruling, quoted verbatim

scripts/check-source-token-ratchet.mjs's own header requires the ruling to be
quoted in the PR that raises a ceiling. Verbatim and untranslated:

business-semantics 棘轮 提升到 100000

The shape it was given, from the same exchange, 选项 A:

解耦:banner 钉实测,ceiling 独立

What changed

file change
scripts/check-source-token-ratchet.mjs CEILINGS['business semantics'] 85,000 -> 100,000; header docblock re-written for the decoupled shape
test/docs-readme-token-figures.test.ts the banner↔ceiling case re-aimed to the truthfulness relation; band table + paragraph re-written
test/source-token-ratchet.test.ts taught the RULED ceiling kind (seat ruling, file surface extended)
README.md banner ~81k -> ~85k, ~39k -> ~37k
.changeset/ratchet-ruled-ceiling-banner-pins-the-measurement.md patch

interaction layer (40,000) and authored total (140,000) are untouched
the ruling names one layer.

Measured on the merged tree

business semantics   ~84,579  (ceiling 85,000 before, 100,000 after)
interaction layer    ~37,447  (ceiling 40,000)
authored total      ~136,366  (ceiling 140,000)

The gate's own Headline line now prints business semantics ~85k · interaction layer ~37k, which is exactly what the README banner states. Re-measured twice:
on the original base a4e5ea3e (84,579 / 37,429 / 136,349, identical to the
dispatch) and again after merging 8223d0aa, where #1605 moved src/views and
carried the interaction layer 18 tokens. It stays well inside the ~37k band, so
no banner figure needed re-cutting — the 5% buffer absorbing routine churn is
exactly its ruled purpose.

Decoupling, and why it is not a constant change

The banner rule asserted row.high > row.ceiling — each layer's banner band had
to close above its committed ceiling — and reasoned from that the ratchet would
fail first on growth. With the coupling intact, raising the ceiling would not
have created headroom: the banner band's upper edge (85,050) would have become
the effective cap, and the assertion would simply have gone red. So the two
numbers are separated and each gets one job. The ceiling is the growth budget,
alone. The banner rule becomes a truthfulness rule: the README figure must track
the measured reading within the ruled 5% buffer. It caps nothing.

The case is re-aimed, not deleted, and the case tying each row's restated
ceiling to CEILINGS stays — that is what stops the README quoting a ceiling
the gate no longer commits. Both banner rows move to the measurement, because it
is one rule and leaving a row on the old basis would mean two rules with no way
to tell which governs.

A ceiling can now be RULED rather than anchored

Every ceiling until now was anchor(reading) — a reading the gate printed, plus
the buffer, rounded up to the next 1,000. A maintainer grant is derived from no
reading, and on this layer none could derive it:

readings whose anchor() === 100,000 : 94,286 .. 95,238
the tree measures                   : 84,579

So the header records a ruled ceiling and deliberately writes no worked
row
for it, rather than reverse-engineering a reading that would produce the
constant. Fabricating a reading here would have been two layers of falsehood —
the row, and the anchoring run the row's date would have had to point at.

test/source-token-ratchet.test.ts modelled every ceiling as anchor() of a
measured reading, so it could not express a grant at all. It now learns the
second kind:

  • RULED_ROW parses a granted ceiling — label, constant, ruling date; the prose
    between them is free, exactly as TABLE_ROW's column widths are.
  • The roster case merges both kinds on document position, so it still asserts
    one row per committed ceiling in the committed order, and remains the vacuity
    guard for both parsers.
  • A new invariant, not a relaxation: a ruled row must restate the committed
    constant, and no reading recorded in the header may anchor to it. Stated
    that way deliberately — "no integer anchors here" is false of every multiple of
    1,000, so the checkable claim is that the readings this file records did not
    produce the constant. That is what stops a ceiling being filed as "ruled" to
    dodge arithmetic that did in fact apply.
  • Every anchored-row case is untouched. Ruled ceilings sit outside the
    "declined as a raise" ledger by construction, which is now said where that case
    reads its input.

Evidence

All runs started after the last edit's mtime; exit codes captured by redirect
first, then $? — never through a pipe.

stage exit
pnpm validate 0
pnpm typecheck 0
pnpm lint 0 (90 pre-existing warnings, none from this diff)
pnpm lint:i18n-gate 0
pnpm hygiene 0
pnpm hygiene:tokens 0
pnpm build 0
pnpm test 0 — Test Files 160 passed (160) · Tests 3392 passed, 1 skipped (3393)

What each run establishes. test/docs-readme-token-figures.test.ts proves
the re-aimed banner rule holds against a live gate reading — it runs the gate in
--json mode and never hard-codes a figure. test/source-token-ratchet.test.ts
proves the header still derives from the constants for both anchored rows (its
anchor(reading), headroom/percentage, run-dating and declined-raise cases all
pass unchanged) and that the ruled row is a grant no recorded reading could
have produced.

Reverse verification, three ablations, each from the committed tree

Every leg: mutate, prove it reached disk by grep -c on both the injected and
the removed text, run, then restore under an EXIT INT TERM trap and prove the
restore by blob hash, not by an exit code.

1. The re-aimed banner case. README banner and its worked row moved together
to ~95k — which keeps the banner-quote, band-edge and ceiling cases green, so
only the new relation is under test:

× is within the ruled 5% buffer of what the gate measures today
× works from a band that actually holds the measured reading
Tests  2 failed | 8 passed (10)

2. The new ruled invariant. The 2026-08-17 run's recorded business-semantics
reading changed 80,356 -> 95,238, which does anchor to 100,000. Exactly one
case fell:

× states a ruled ceiling as ruled, and proves no recorded reading anchored it
Tests  1 failed | 21 passed (22)

3. The vacuity guard for the new parser. The ruled row deleted outright:

× carries exactly one row per committed ceiling, of either kind, in the committed order
Tests  1 failed | 21 passed (22)

Restores verified: scripts/check-source-token-ratchet.mjs back to
8bb0b432…, README.md to 0ea08478…, test/docs-readme-token-figures.test.ts
to 65f86a16…; git diff HEAD empty after each.

⚠️ Honest limit, on ablation 1 only. That case cannot fire alone — the rows
are pinned to the README banner and to BUFFER, so measured in band is
entailed by the tolerance case. It can fail, so it is not a tautology, but it is
a row-level restatement holding the published, rounded band accountable rather
than an independent relation. I considered pinning the inverted relation
instead (row.high below row.ceiling, true on both layers now and genuinely
independent) and rejected it: making the banner rule's verdict depend on the
ceiling again is precisely the coupling 「解耦」 removed. Ablations 2 and 3 do
each fire alone.

Two consequences recorded, not silently absorbed

  1. ⚠️ The gate now nags to undo the ruling. At 84,579 against 100,000 the
    headroom is over twice the buffer, so every run prints
    re-anchor this ceiling to ~89,000 in your PR. Following it hands back the
    headroom the ruling created. The header now states plainly that a ruled
    ceiling is not tightened on that line alone — it moves on another ruling,
    or on a PR that genuinely shrinks the layer and says so. ⛔ The advisory's
    firing condition is unchanged: changing when a gate speaks is its own
    decision, and the seat is filing it separately, fenced behind this PR.
  2. The dispatch's Zone 3 prediction was falsified, and the seat has accepted
    it.
    It expected "on growth the ratchet fails first" to become true by
    construction. It becomes false: both bands now close below their ceiling
    (89,250 vs 100,000; 38,850 vs 40,000), so the banner rule reddens first on
    both layers. Not the coupling returning — the two reds are paid in different
    currencies (a README restatement any PR may do, against a shrink or a ruling).
    The re-written paragraph therefore stops reasoning from that comparison
    altogether rather than asserting its inverse.

Guardrails observed

  • ⛔ No repo-wide replace of 100,000 / 100000 / $100K — the opportunity
    approval threshold in content/docs/** and test/deal-threshold-parity.test.ts
    is untouched. Only CEILINGS and the token-figure surfaces moved.
  • ⛔ The run-when-main footer comment (landed shortly before this branch) is
    untouched; the docblock work is the re-anchoring block near the top.
  • ⛔ Nothing under src/. ⛔ No new gate built — an existing suite learned a
    concept and gained an invariant. ⛔ Only the two test/** files the claim and
    the seat's ruling name; no deletions in test/**.
  • No site-absolute /docs/… links introduced in README.md or the changeset.
  • No control characters: grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]' clean on
    all five files.
  • Draft, not enqueued, auto-merge not enabled, assignee untouched, no second
    claim comment — the seat lands it.

Generated by Claude Code

…ouple the banner

Raise CEILINGS['business semantics'] 85,000 -> 100,000 on the 2026-09-05
maintainer ruling, quoted verbatim in the PR body as this gate's header
requires. The interaction layer and the authored total are untouched.

Introduce the distinction the raise forces: a ceiling is now either ANCHORED
(anchor(reading), shrink-only, owes a worked row) or RULED (a maintainer grant,
derived from no reading). No real reading anchors to 100,000 -- that needs one
between 94,286 and 95,238 and the tree measures 84,579 -- so the header records
the ruled kind and writes no worked row rather than fabricating a reading.

Decouple the README banner from the ceiling. The banner rule was asserting that
each layer's band closed above its ceiling and reasoning that the ratchet failed
first on growth; that coupling would have made the banner band the effective cap
and defeated the raise. It is re-aimed, not deleted: the banner must track the
MEASURED reading within the ruled buffer. The case tying each row's restated
ceiling to CEILINGS stays. Both banner figures move to the measurement --
business semantics ~81k -> ~85k, interaction layer ~39k -> ~37k -- because it is
one rule and leaving a row on the old basis would mean two.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018xtjdpZFjgWh4Ad9Wcx68J
@vercel

vercel Bot commented Sep 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Sep 5, 2026 11:31pm UTC

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation ci/cd CI plumbing and the verification pipeline labels Sep 5, 2026
The suite modelled every ceiling as anchor() of a measured reading, so a
maintainer grant could not be expressed in it at all: the "one worked row per
committed ceiling" case went red on the ruled row no matter how the header was
written, and no honest reading exists that anchors to 100,000 (that needs
94,286..95,238; the tree measures 84,579).

Teach it the second kind rather than relax it. RULED_ROW parses a granted
ceiling; the roster case now merges both kinds on document position, so it still
asserts one row per committed ceiling in the committed order and remains the
vacuity guard for both parsers. Every anchored-row case is untouched.

The new case is an added invariant, not a weaker one: a ruled row's ceiling must
be the committed constant, and no reading recorded in the header may anchor to
it. Stated that way on purpose -- "no integer anchors here" is false of every
multiple of 1,000, so the checkable claim is that the readings this file records
did not produce the constant. That is what stops a ceiling being filed as ruled
to dodge arithmetic that did in fact apply.

Ruled ceilings are outside the declined-as-a-raise ledger by construction, which
is now stated where that case reads its input.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018xtjdpZFjgWh4Ad9Wcx68J
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd CI plumbing and the verification pipeline documentation Improvements or additions to documentation

Projects

None yet

2 participants